package com.yonyou.gmmc.service.wechatpush.event.handler;

import org.marketing.common.constants.MessagePushConstant;
import org.marketing.common.dto.EventDataDTO;
import org.marketing.common.entity.wechatpushmessage.WeChatMessageProtocol;
import org.marketing.common.entity.wechatpushmessage.WeChatMessageProtocolHandleInfo;
import org.marketing.common.event.BizEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.ApplicationListener;


import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.yonyou.gmmc.service.wechatpush.event.exception.PushException;
import com.yonyou.gmmc.service.wechatpush.mq.entrance.MessageSender;
import com.yonyou.gmmc.service.wechatpush.provider.PushThreadCallable;
import com.yonyou.gmmc.service.wechatpush.provider.PushThreadCallback;
import com.yonyou.gmmc.service.wechatpush.resolver.MessageResolver;
import com.yonyou.gmmc.service.wechatpush.resolver.PushMessage;
import com.yonyou.gmmc.service.wechatpush.util.SpringUtil;

public class AbstractEventHandle {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	protected String backInfo = "";
    @Autowired
    private MessageResolver messageResolver;

//    @Autowired
//    private MessageSender messageSender;
    @Autowired
    private ApplicationContext context;

    @Autowired
    public ListeningExecutorService executorService;

	public String getBackInfo() {
		return backInfo;
	}
	private void init(){
		messageResolver=(MessageResolver)SpringUtil.getBean("messageResolverImpl");
		context=SpringUtil.getApplicationContext();
	}

	/**
	 * 具体的业务描述
	 * 
	 * @return
	 */
	protected String getHandleInfo(){
		return "";
	}

	/**
	 * 预处理数据
	 * 
	 * @param event
	 * @return
	 */
	protected EventDataDTO preCheck(BizEvent event){
		return null;
	}

	/**
	 * 具体处理的逻辑
	 * 
	 * @param event
	 * @return
	 */
	protected boolean push(EventDataDTO data) throws PushException{
		return true;
	}

	/**
	 * 处理完成后进行的逻辑判断
	 */
	protected void afterPush(){
		
	}

	/**
	 * 事件处理
	 * 
	 * @param event
	 * @return
	 */
	public HandleResult handleing(BizEvent event) {
		logger.info("推送服务开始处理事件，对应处理的逻辑为【" + this.getHandleInfo() + "】");

		HandleResult handleResult = new HandleResult();

		try {
			EventDataDTO o = this.preCheck(event);//预处理 转换业务对象
			handleResult.setHandle(true);
			handleResult.setPushed(push(o));//处理积分发放，是否发放了积分
			handleResult.setMessage(getBackInfo());//返回的消息
		} catch (PushException e) {
			logger.error("积分事件处理失败，异常" + e);
			handleResult.setHandle(false);
			handleResult.setPushed(false);
			handleResult.setMessage(getBackInfo());
			//e.printStackTrace();
		}

		return handleResult;

	}
	public void sendNotify(WeChatMessageProtocol protocol) {
		this.init();
        logger.debug("start to listen");
        logger.debug("protocol is "+protocol);
        //获取处理信息
        WeChatMessageProtocolHandleInfo newHandleInfo = WeChatMessageProtocolHandleInfo.init(protocol.getHandleInfo());
        protocol.setHandleInfo(newHandleInfo);
        //丢弃消息
        if(newHandleInfo.isDeprive()){
            logger.error("deprive message "+protocol);
            return;
        }
        //转换为协议消息
        PushMessage pushMessage=messageResolver.receiveMessage(protocol);
        //验证协议消息
        if(!messageResolver.validateMessage(pushMessage)){
            logger.error("message validate error");
//            newHandleInfo.addHandleSimpleHistory("message validate error");
//            protocol.setHandleInfo(newHandleInfo);
//            messageSender.send(protocol);
            return;
        }
        //转入发送线程
        PushThreadCallable pushThreadCallable = context.getBean(MessagePushConstant.PROVIDER_THREAD,PushThreadCallable.class);
        pushThreadCallable.setProviderMessage(pushMessage);
        PushThreadCallback pushThreadCallback = context.getBean(PushThreadCallback.class,protocol);
        Futures.addCallback(executorService.submit(pushThreadCallable),pushThreadCallback);
        logger.debug("end to listen " );
    }
}
